type MessageHandler = (data: any) => void;

// 声明全局 electronAPI 类型
declare global {
    interface Window {
        electronAPI?: {
            getProcessId?: () => number;
            getServerPorts?: () => Promise<any>;
            onPortsUpdate?: (callback: (ports: any) => void) => () => void;
        };
    }
}

export class WebsocketIo {
    private static instances: Map<string, WebsocketIo> = new Map();
    private websocketInstance: WebSocket | null = null;
    private url: string = "";
    private messageHandlers: Map<string, MessageHandler[]> = new Map();
    private globalHandler: MessageHandler | null = null; // 新增：用于存储全局处理器
    public onOpen: (() => void) | null = null;
    public onClose: (() => void) | null = null;
    public onError: ((error: Event) => void) | null = null;
    private reconnectTimer: number | null = null;
    private checkConnectionTimer: number | null = null;
    private reconnectAttempts: number = 0;
    private maxReconnectAttempts: number = 360;
    private currentGatewayIp: string = ""; // 存储当前激活的网关IP
    private processId: string; // 进程标识

    // 构造函数现在只进行初始化，不自动连接
    private constructor(processId: string) {
        this.processId = processId;
        console.log(`WebSocket实例已创建，等待连接指令 [${this.processId}]`);
    }

    static getInstance(processId?: string): WebsocketIo {
        const pid = processId || this.getProcessId();
        if (!this.instances.has(pid)) {
            this.instances.set(pid, new WebsocketIo(pid));
            console.log(`创建新的WebSocket实例: ${pid}`);
        }
        return this.instances.get(pid)!;
    }

    /**
     * 新增：设置一个全局的、唯一的消���处理器
     * 这个处理器将在连接成功后自动绑定。
     * @param handler - The message handler function.
     */
    setGlobalHandler(handler: MessageHandler) {
        console.log(`[${this.processId}] 设置全局消息处理器。`);
        this.globalHandler = handler;
    }

    private static getProcessId(): string {
        try {
            if (typeof window !== 'undefined' && window.electronAPI?.getProcessId) {
                return `electron_${window.electronAPI.getProcessId()}`;
            }
        } catch (error) {
            console.warn('无法获取Electron进程ID:', error);
        }
        const sessionKey = 'websocket_process_id';
        let processId = '';
        try {
            if (typeof window !== 'undefined' && window.sessionStorage) {
                processId = window.sessionStorage.getItem(sessionKey) || '';
            }
        } catch (error) {
            console.warn('无法访问sessionStorage:', error);
        }
        if (!processId) {
            processId = `web_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
            try {
                if (typeof window !== 'undefined' && window.sessionStorage) {
                    window.sessionStorage.setItem(sessionKey, processId);
                }
            } catch (error) {
                console.warn('无法设置sessionStorage:', error);
            }
        }
        return processId;
    }

    getProcessId(): string {
        return this.processId;
    }

    static getAllInstances(): Map<string, WebsocketIo> {
        return this.instances;
    }

    static getInstanceCount(): number {
        return this.instances.size;
    }

    websocketIsNormal(): boolean {
        return this.websocketInstance?.readyState === WebSocket.OPEN;
    }

    sendMessage(message: any): boolean {
        if (!this.websocketInstance || !this.websocketIsNormal()) {
            console.warn(`[${this.processId}] 尝试在连接关闭时发送消息:`, message);
            return false;
        }
        this.websocketInstance.send(message);
        return true;
    }

    // 连接检查现在由 connectWebsocket 启动
    private startConnectionChecker() {
        if (this.checkConnectionTimer) {
            clearInterval(this.checkConnectionTimer);
        }
        this.checkConnectionTimer = setInterval(() => {
            if (!this.url) {
                return;
            }
            if (this.websocketIsNormal()) {
                this.reconnectAttempts = 0;
            } else {
                console.log(`[${this.processId}] 连接断开，准备重连...`);
                this.reconnectWebsocket();
            }
        }, 10000);
    }

    private reconnectWebsocket() {
        if (this.reconnectAttempts >= this.maxReconnectAttempts) {
            console.log(`[${this.processId}] 达到最大重连次数，停止重连。`);
            return;
        }
        if (this.reconnectTimer) {
            clearTimeout(this.reconnectTimer);
        }
        this.reconnectTimer = setTimeout(() => {
            this.reconnectAttempts++;
            console.log(`[${this.processId}] 重连尝试 ${this.reconnectAttempts}/${this.maxReconnectAttempts}`);
            this.connectWebsocket(this.url); // 使用保存的url进行重连
        }, Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000));
    }

    // 这是现在唯一的连接入口点
    connectWebsocket(url: string) {
        if (!url) {
            console.error(`[${this.processId}] 连接失败：URL为空。`);
            return;
        }
        console.log(`[${this.processId}] 接到连接指令，URL: ${url}`);
        this.url = url;
        this.reconnectAttempts = 0; // 每次新的手动连接都重置尝试次数

        if (this.reconnectTimer) clearTimeout(this.reconnectTimer);

        if (this.websocketInstance) {
            this.websocketInstance.onopen = null;
            this.websocketInstance.onclose = null;
            this.websocketInstance.onerror = null;
            this.websocketInstance.onmessage = null;
            this.websocketInstance.close();
        }

        const separator = url.includes('?') ? '&' : '?';
        const urlWithProcessId = `${url}${separator}processId=${encodeURIComponent(this.processId)}&timestamp=${Date.now()}`;
        
        console.log(`[${this.processId}] 正在连接到: ${urlWithProcessId}`);
        this.websocketInstance = new WebSocket(urlWithProcessId);

        this.websocketInstance.onopen = () => {
            console.log(`[${this.processId}] WebSocket 连接成功。`);
            this.reconnectAttempts = 0;
            if (this.currentGatewayIp) {
                console.log(`[${this.processId}] 重新订阅网关:`, this.currentGatewayIp);
                this.sendMessage(JSON.stringify({
                    action: "taggleGateway",
                    gatewayIp: this.currentGatewayIp
                }));
            }
            if (this.onOpen) this.onOpen();
            this.setupMessageListener(); // 修改点：使用统一的监听器设置
        };

        this.websocketInstance.onclose = () => {
            if (this.onClose) this.onClose();
            console.log(`[${this.processId}] 连接已关闭。`);
            // onclose时不再自动重连，交由 checkConnectionTimer 处理
        };

        this.websocketInstance.onerror = (error) => {
            if (this.onError) this.onError(error);
            console.error(`[${this.processId}] WebSocket 连接错误:`, error);
        };

        // 成功发起连接后，启动连接状态检查器
        this.startConnectionChecker();
    }

    private setupMessageListener() {
        if (!this.websocketInstance) return;
        this.websocketInstance.onmessage = (e: MessageEvent) => {
            // 优先使用全局处理器
            if (this.globalHandler) {
                try {
                    const data = JSON.parse(e.data);
                    this.globalHandler(data);
                } catch (error) {
                     console.error(`[${this.processId}] 全局处理器处理消息失败:`, error, e.data);
                }
                return; // 如果有全局处理器，则不再执行旧的逻辑
            }

            // --- 旧的、基于action的处理器逻辑（保留作为备用） ---
            try {
                const data = JSON.parse(e.data);
                const action = data.action || 'default';
                if (this.messageHandlers.has(action)) {
                    this.messageHandlers.get(action)!.forEach(handler => handler(data));
                }
                if (action !== 'default' && this.messageHandlers.has('default')) {
                    this.messageHandlers.get('default')!.forEach(handler => handler(data));
                }
            } catch (error) {
                console.error(`[${this.processId}] 处理消息失败:`, error, e.data);
            }
        };
    }

    // 旧的 addMessageHandler 保持不变，以防其他地方用到
    addMessageHandler(handler: MessageHandler, action: string = 'default') {
        if (!this.messageHandlers.has(action)) {
            this.messageHandlers.set(action, []);
        }
        const handlers = this.messageHandlers.get(action)!;
        if (!handlers.includes(handler)) {
            handlers.push(handler);
        }
    }

    removeMessageHandler(handler: MessageHandler, action: string = 'default') {
        if (this.messageHandlers.has(action)) {
            const handlers = this.messageHandlers.get(action)!.filter(h => h !== handler);
            if (handlers.length === 0) {
                this.messageHandlers.delete(action);
            } else {
                this.messageHandlers.set(action, handlers);
            }
        }
    }

    setCurrentGatewayIp(gatewayIp: string) {
        this.currentGatewayIp = gatewayIp;
        console.log(`[${this.processId}] 设置当前网关IP:`, gatewayIp);
    }

    getCurrentGatewayIp(): string {
        return this.currentGatewayIp;
    }

    dispose() {
        console.log(`[${this.processId}] 清理WebSocket资源...`);
        if (this.checkConnectionTimer) clearInterval(this.checkConnectionTimer);
        if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
        if (this.websocketInstance) {
            this.websocketInstance.close();
        }
        this.messageHandlers.clear();
        this.globalHandler = null; // 清理全局处理器
        this.currentGatewayIp = "";
        this.url = "";
    }

    static disposeInstance(processId: string): boolean {
        const instance = this.instances.get(processId);
        if (instance) {
            instance.dispose();
            this.instances.delete(processId);
            console.log(`已清理WebSocket实例: ${processId}`);
            return true;
        }
        return false;
    }

    static disposeAllInstances(): void {
        console.log(`清理所有WebSocket实例，共${this.instances.size}个`);
        this.instances.forEach((instance) => instance.dispose());
        this.instances.clear();
    }
    
    getInstanceStatus() {
        return {
            processId: this.processId,
            isConnected: this.websocketIsNormal(),
            connectionUrl: this.url,
            messageHandlerCount: Array.from(this.messageHandlers.values()).reduce((total, handlers) => total + handlers.length, 0),
            globalHandlerSet: !!this.globalHandler, // 新增状态
            currentGatewayIp: this.currentGatewayIp,
            reconnectAttempts: this.reconnectAttempts
        };
    }
}

export default WebsocketIo;

if (typeof window !== 'undefined') {
    (window as any).WebsocketIo = WebsocketIo;
}
